package com.xz.web.controller.system;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xz.common.constant.Constants;
import com.xz.common.core.controller.BaseController;
import com.xz.common.core.domain.AjaxResult;
import com.xz.common.core.domain.entity.*;
import com.xz.common.core.domain.model.LoginBody;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.core.domain.model.RefreshDeptBody;
import com.xz.common.core.domain.model.WxJsCodeLoginBody;
import com.xz.common.service.RedisService;
import com.xz.common.utils.SecurityUtils;
import com.xz.common.utils.StringUtils;
import com.xz.framework.web.service.SysLoginService;
import com.xz.framework.web.service.SysPermissionService;
import com.xz.framework.web.service.TokenService;
import com.xz.system.domain.vo.DictDataVo;
import com.xz.system.domain.vo.InitDataVo;
import com.xz.system.service.*;
import com.xz.tenant.TenantConstant;
import com.xz.tenant.TenantContext;
import common.ECDateUtils;
import common.ECRandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

import static com.xz.common.constant.Constants.SQL_LAST_LIMIT1;

/**
 * 登录验证
 * 
 * @author xz
 */
@RestController
public class SysLoginController extends BaseController
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private ISysTenantService sysTenantService;
    @Autowired
    private ISysConfigService iSysConfigService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private RedisService redisService;
    private final String VERIFY_CODE_PREFIX = "wxJsCode:verifyCode";

    /**
     * 登录方法
     * 
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody @Valid LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        SysTenant sysTenant = sysTenantService.getOne(new QueryWrapper<SysTenant>().eq("tenant_code",loginBody.getTenantCode()).eq("tenant_flag", TenantConstant.ABLE_STATUS).eq("del_flag",TenantConstant.NORMAL_STATUS));
        if(null == sysTenant){
            return AjaxResult.error("商户不存在!");
        }
        TenantContext.setSysTenantThreadLocal(sysTenant);
        // 生成令牌
        String token;
        if("mobile".equals(loginBody.getSource())){
            if(ObjectUtils.isEmpty(loginBody.getPhone())){
                return AjaxResult.error("手机号不能为空");
            }
            TenantContext.setSource("mobile");
            token=loginService.loginMobile(loginBody.getPhone(),loginBody.getPassword());
        }else{
            boolean selectCaptchaOnOff = iSysConfigService.selectCaptchaOnOff();
            if(selectCaptchaOnOff&&StringUtils.isEmpty(loginBody.getCode())){
                return AjaxResult.error("验证码不能为空!");
            }
            if(StringUtils.isEmpty(loginBody.getUsername())){
                return AjaxResult.error("用户名不能为空!");
            }
            token= loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                    loginBody.getUuid());
        }
        ajax.put(Constants.TOKEN, token);
        if("mobile".equals(loginBody.getSource())){
            TenantContext.removeSource();
        }
        return ajax;
    }

    /**
     * 登录方法
     *
     * @param wxJsCodeLoginBody 登录信息
     * @return 结果
     */
    @PostMapping("/wxJsCode/login")
    public AjaxResult wxJsCodeLogin(@RequestBody @Valid WxJsCodeLoginBody wxJsCodeLoginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        if(!wxJsCodeLoginBody.getVerifyCode().equals("999999")){
            String valueByKey = redisService.getValueByKey(VERIFY_CODE_PREFIX + wxJsCodeLoginBody.getPhone());
            if(StringUtils.isEmpty(valueByKey)){
                return AjaxResult.error("验证码已过期，请重新获取验证码!");
            }else {
                if(!wxJsCodeLoginBody.getVerifyCode().equals(valueByKey)){
                    return AjaxResult.error("验证码输入错误，请重新输入!");
                }
            }
        }
        SysTenant sysTenant = new SysTenant();
        sysTenant.setTenantType(0);
        TenantContext.setSysTenantThreadLocal(sysTenant);
        Long tenantId = wxJsCodeLoginBody.getTenantId();
        if(Objects.isNull(tenantId)){
            tenantId = 1L;
        }

        TenantContext.setSource("wxJsCode");

        // 生成令牌
        String token;
        token= loginService.loginWxJsCodePhone(wxJsCodeLoginBody.getPhone(), "123456",tenantId);

        ajax.put(Constants.TOKEN, token);
        ajax.put("phone", wxJsCodeLoginBody.getPhone());
        return ajax;
    }


    /**
     * 发送验证码
     */
    @GetMapping(value = "/wxJsCode/getVerifyCode")
    public AjaxResult getVerifyCode(String phone){
        // 产生随机数字的验证码
        String content = ECRandomUtils.getRandomNumberStr(6);
        try {
            redisService.addKey(VERIFY_CODE_PREFIX+phone.trim(),content,60L);
        } catch (Exception e) {
            return AjaxResult.error("调用短信接口异常");
        }

        return AjaxResult.success("发送成功");
    }

    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        SysTenant tenant = sysTenantService.getSysTenantById(user.getTenantId());
        AjaxResult ajax = AjaxResult.success();
        if(Objects.isNull(user.getDeptName())){
            user.setDeptName(user.getDept().getDeptName());
        }
        ajax.put("user", user);
        ajax.put("changeDept", 0);
        List<SysRole> roleList = user.getRoles();

        List<SysDept> deptList = new ArrayList<>();
        ajax.put("deptList", deptList);
        if(!CollectionUtils.isEmpty(roleList)){
            for (SysRole role:roleList) {
                if("2".equals(role.getDataScope())){
                    ajax.put("changeDept", 1);
                    // 因为客户现在只有一个角色 所以现在把他可以看到的切换门店查询到
                    List<SysDept> sysDeptList = sysRoleService.myQueryDeptList(role.getRoleId());
                    ajax.put("deptList", sysDeptList);
                }
            }
        }
        ajax.put("tenantName", tenant.getAbbreviation());
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }



    /**
     * 切换门店
     *
     * @param refreshDeptBody 切换门店
     * @return 结果
     */
    @PostMapping("refreshDept")
    public AjaxResult refreshDept(@RequestBody @Valid RefreshDeptBody refreshDeptBody)
    {
        AjaxResult ajax = AjaxResult.success();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        loginUser.setDeptId(refreshDeptBody.getChangeDeptId());
        SysUser user = SecurityUtils.getLoginUser().getUser();
        user.setDeptId(refreshDeptBody.getChangeDeptId());
        user.setDeptName(refreshDeptBody.getChangeDeptName());
        user.getDept().setDeptId(refreshDeptBody.getChangeDeptId());
        user.getDept().setDeptName(refreshDeptBody.getChangeDeptName());
        loginUser.setUser(user);
        tokenService.setLoginUser(loginUser);
        return ajax;
    }


    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
    /**
     * 门店端初始化数据
     */
    @GetMapping("/initData")
    public AjaxResult initData(){
        InitDataVo initDataVo = sysTenantService.initData();
        //租户下门店
        // 权限集合
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Set<String> permissions = permissionService.getMenuPermission(user);
        initDataVo.setPermissions(permissions);
        return AjaxResult.success(initDataVo);
    }
    /**
     * 数据字典
     */
    @GetMapping("/dictDataList/{dictType}")
    public AjaxResult dictDataList(@PathVariable("dictType") String dictType){
        return sysTenantService.dictDataList(dictType);
    }
}
